package com.canbot.u05.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import com.canbot.u05.R;
import com.canbot.u05.bean.guide.IMapPointBean;
import com.canbot.u05.bean.guide.LocalPointsBean;
import com.canbot.u05.utils.Config;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by zmp on 2017/5/16.
 * 用于地图任务界面加载
 */

public class MyMapTaskView extends View {


        private final Paint bgPaint;

        private Paint textPaint;

        private GestureDetector mGestureDetector;

        private Bitmap pointerBitmap;

        private Bitmap mBitmap;

        private int measuredWidth;

        private int measuredHeight;

        private static final String TAG = "MyMapTaskView";

        private IOnStateListener mOnStateListner;

        private int pointerWidth;

        private int pointerhight;

        private int maxWidth;

        private int maxHeight;

        private int mImageWidth;

        private int mImageHeight;

        private List<IMapPointBean> mList;
        private int baseline;


        public void setScale(float scale) {
                this.scale = scale;
                this.maxWidth = (int) (mImageWidth * scale + 100);
                this.maxHeight = (int) (mImageHeight * scale + 100);
                //设置字体大小
                textPaint.setTextSize(30);
                Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
                baseline = (fontMetrics.bottom + fontMetrics.top) / 2;
                setPointerScale();
                requestUpdateBitmap();
        }

        public float scale = 6;

        private BitmapRegionDecoder mDecoder;

        private BitmapFactory.Options options;

        public MyMapTaskView(Context context) {
                this(context, null);
        }

        public MyMapTaskView(Context context, @Nullable AttributeSet attrs) {
                this(context, attrs, 0);
        }

        public MyMapTaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
                super(context, attrs, defStyleAttr);
                mGestureDetector = new GestureDetector(getContext(), new MyOnGestureListener());
                pointerBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.map_pointer);
                pointerWidth = pointerBitmap.getWidth();
                pointerhight = pointerBitmap.getHeight();
                Log.e(TAG, "pointerWidth：" + pointerWidth);
                Log.e(TAG, "pointerhight：" + pointerhight);
                textPaint = new Paint();
                //设置字体大小
                textPaint.setTextSize(30);
                textPaint.setTextAlign(Paint.Align.CENTER);
                textPaint.setStrokeWidth(2);
                textPaint.setAntiAlias(true);
                textPaint.setColor(Color.WHITE);
                Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
                baseline = (fontMetrics.bottom + fontMetrics.top) / 2;
                bgPaint = new Paint();
                bgPaint.setAntiAlias(true);
                bgPaint.setStyle(Paint.Style.FILL);
                bgPaint.setColor(Color.parseColor("#DD333333"));
        }

        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
                super.onSizeChanged(w, h, oldw, oldh);
                measuredWidth = getMeasuredWidth();
                measuredHeight = getMeasuredHeight();
                initBitmap();
        }

        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouchEvent(MotionEvent event) {
                int action = event.getAction();
                if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                        requestUpdateBitmap();
                }
                mGestureDetector.onTouchEvent(event);
                return true;
        }

        int decoderX;

        int decoderY;

        private void requestUpdateBitmap() {
                if (options == null) {
                        return;
                }
                decoderX -= initDotX;
                decoderY -= initDotY;
                initDotX = 0;
                initDotY = 0;

                Log.e("initDotX", "decoderX:" + decoderX + ",decoderY:" + decoderY);

                if (decoderX > maxWidth - measuredWidth - 100) {
                        initDotX = -(decoderX - maxWidth + measuredWidth + 100);
                        decoderX = maxWidth - measuredWidth - 100;
                        if (decoderX < -100) {
                                initDotX = 100;
                                decoderX = 0;
                        }
                } else if (decoderX < 0) {
                        initDotX = -decoderX;
                        decoderX = 0;
                }
                Log.e("initDotX", "initDotX:" + initDotX + "," + initDotY);
                if (initDotX > 100) {
                        initDotX = 100;
                }
                if (initDotX < -100) {
                        initDotX = -100;
                }


                if (decoderY > maxHeight - measuredHeight - 100) {
                        initDotY = -(decoderY - maxHeight + measuredHeight + 100);
                        decoderY = maxHeight - measuredHeight - 100;
                        if (decoderY < -100) {
                                initDotY = 100;
                                decoderY = 0;
                        }
                } else if (decoderY < 0) {
                        initDotY = -decoderY;
                        decoderY = 0;
                }
                if (initDotY < -100) {
                        initDotY = -100;
                }
                if (initDotY > 100) {
                        initDotY = 100;
                }
                Log.e(TAG, decoderY + "--decoderY--decoderX--" + decoderX);
                Log.e(TAG, initDotX + "--initDotX--initDotY--" + initDotY);
                options.inSampleSize = (int) (1 / scale);
                options.inScaled = true;
                Bitmap bitmap = mDecoder.decodeRegion(new Rect((int) (decoderX / scale), (int) (decoderY / scale), (int) (measuredWidth / scale + decoderX / scale),
                        (int) (measuredHeight / scale + decoderY / scale)), options);
                this.mBitmap = Bitmap.createScaledBitmap(bitmap, measuredWidth, measuredHeight, false);
                invalidate();
        }

        RectF oval = new RectF();

        float initDotX = 0f;

        float initDotY = 0f;

        @Override
        protected void onDraw(Canvas canvas) {
                super.onDraw(canvas);
                if (mBitmap != null) {
                        canvas.drawBitmap(mBitmap, initDotX, initDotY, null);
                }
                canvas.clipRect(0, 0, measuredWidth, measuredHeight);
                for (int i = 0; i < mPointerList.size(); i++) {
                        IMapPointBean pointer = mPointerList.get(i);
                        canvas.drawBitmap(pointerBitmap, pointer.getX() - pointerWidth / 2F + initDotX - decoderX,
                                pointer.getY() - pointerhight + 5 + initDotY - decoderY, null);
                        String name = pointer.getPointName();
                        oval.left = pointer.getX() - name.length() * 15 - 20 + initDotX - decoderX;
                        oval.bottom = pointer.getY() - pointerhight - 5 + initDotY - decoderY;
                        oval.right = oval.left + name.length() * 30 + 40;
                        oval.top = oval.bottom - 50;
                        canvas.drawRoundRect(oval, 50, 50, bgPaint);
                        canvas.drawText(name, pointer.getX()+ initDotX - decoderX, oval.centerY() - baseline, textPaint);
                        mRectList.get(i).set(pointer.getX() - pointerWidth / 2F + initDotX - decoderX,
                                pointer.getY() - pointerhight + initDotY - decoderY,
                                pointer.getX() + pointerWidth / 2F + initDotX - decoderX,
                                pointer.getY() + initDotY - decoderY);
                }
        }

        private List<RectF> mRectList = new ArrayList<>();

        private List<IMapPointBean> mPointerList = new ArrayList<>();

        /**
         * 初始化地图数据
         *
         * @param path
         */
        public void setMapPhoto(String path) throws FileNotFoundException {
                FileInputStream inputStream = null;
                inputStream = new FileInputStream(path);
                BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
                tmpOptions.inSampleSize = 1;
                tmpOptions.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(inputStream, null, tmpOptions);
                mImageWidth = tmpOptions.outWidth;
                mImageHeight = tmpOptions.outHeight;
                Log.e(TAG, mImageWidth + "——-tmpOptions——-" + mImageHeight);
                this.maxWidth = (int) (mImageWidth * scale + 100);
                this.maxHeight = (int) (mImageHeight * scale + 100);
                Log.e(TAG, maxWidth + "——-maxWidth-maxWidth——-" + maxHeight);
                try {
                        inputStream = new FileInputStream(path);
                        mDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
                } catch (IOException e) {
                        e.printStackTrace();
                        Log.e(TAG, "--mDecoder--" + e.getMessage());
                }
                options = new BitmapFactory.Options();
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                initBitmap();
        }

        private void initBitmap() {
                if (mDecoder == null) {
                        return;
                }
                if (measuredWidth == 0 && measuredHeight == 0) {
                        return;
                }
                options.inSampleSize = (int) (1 / scale);
                options.inScaled = true;
                Bitmap bitmap = mDecoder.decodeRegion(new Rect(0, 0, (int) (measuredWidth / scale), (int) (measuredHeight / scale)), options);
                this.mBitmap = Bitmap.createScaledBitmap(bitmap, measuredWidth, measuredHeight, false);
                postInvalidate();
        }


        /**
         * 初始化地图数据
         *
         * @param inputStream
         */
        public void setMapPhoto(InputStream inputStream) {
                BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
                tmpOptions.inSampleSize = 1;
                tmpOptions.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(inputStream, null, tmpOptions);
                mImageWidth = tmpOptions.outWidth;
                mImageHeight = tmpOptions.outHeight;
                Log.e(TAG, mImageWidth + "——-tmpOptions——-" + mImageHeight);
                this.maxWidth = (int) (mImageWidth * scale + 100);
                this.maxHeight = (int) (mImageHeight * scale + 100);
                Log.e(TAG, maxWidth + "——-maxWidth-maxWidth——-" + maxHeight);
                try {
                        mDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
                } catch (IOException e) {
                        e.printStackTrace();
                }
                options = new BitmapFactory.Options();
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                initBitmap();
        }

        /**
         * 初始化地图数据
         *
         * @param bytes
         */
        public void setMapPhoto(byte[] bytes) {
                BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
                tmpOptions.inSampleSize = 1;
                tmpOptions.inJustDecodeBounds = true;
                BitmapFactory.decodeByteArray(bytes, 0, bytes.length, tmpOptions);
                mImageWidth = tmpOptions.outWidth;
                mImageHeight = tmpOptions.outHeight;
                this.maxWidth = (int) (mImageWidth * scale + 100);
                this.maxHeight = (int) (mImageHeight * scale + 100);
                Log.e(TAG, maxWidth + "---maxWidth-maxWidth--" + maxHeight);
                try {
                        mDecoder = BitmapRegionDecoder.newInstance(bytes, 0, bytes.length, false);
                } catch (IOException e) {
                        e.printStackTrace();
                }
                options = new BitmapFactory.Options();
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                if (mImageWidth < measuredWidth) {
                        measuredWidth = mImageWidth;
                }
                if (mImageHeight < measuredHeight) {
                        measuredHeight = mImageHeight;
                }
                initBitmap();
        }

        /**
         * 设置地图位置点
         *
         * @param list
         */
        public void setMapPoints(List<IMapPointBean> list) {
                this.mList = list;
                this.mPointerList.clear();
                this.mRectList.clear();
                for (IMapPointBean pointer : list) {
                        LocalPointsBean bean = new LocalPointsBean(pointer.getX() * scale, pointer.getY() * scale, pointer.getPointName());
                        this.mPointerList.add(bean);
                        mRectList.add(new RectF(pointer.getX() - pointerWidth / 2, pointer.getY() - pointerhight, pointer.getX() + pointerWidth / 2, pointer.getY()));
                }
                postInvalidate();
        }

        private void setPointerScale() {
                if (mList != null) {
                        for (int i = 0; i < mList.size(); i++) {
                                IMapPointBean pointBean = mList.get(i);
                                IMapPointBean iMapPointBean = mPointerList.get(i);
                                RectF rectF = mRectList.get(i);
                                iMapPointBean.setX(pointBean.getX() * scale);
                                iMapPointBean.setY(pointBean.getY() * scale);
                                rectF.set(pointBean.getX() - pointerWidth / 2, pointBean.getY() - pointerhight, pointBean.getX() + pointerWidth / 2, pointBean.getY());
                        }
                }
        }

        /**
         * 设置地图位置点
         * 相对坐标左下改为左上
         *
         * @param list
         */
        public void setMapPoints2(List<IMapPointBean> list) {
                this.mPointerList.clear();
                this.mRectList.clear();
                for (IMapPointBean pointer : list) {
                        LocalPointsBean bean = new LocalPointsBean(
                                pointer.getX() * scale
                                , maxHeight - 100 - pointer.getY() * scale
                                , pointer.getPointName());
                        this.mPointerList.add(bean);
                        mRectList.add(new RectF(pointer.getX() - pointerWidth / 2, pointer.getY() - pointerhight, pointer.getX() + pointerWidth / 2, pointer.getY()));
                }
                initBitmap();
        }

        /**
         * 设置地图位置点
         * 相对坐标左下改为中间
         *
         * @param list
         */
        public void setMapPoints3(List<IMapPointBean> list) {
                this.mPointerList.clear();
                this.mRectList.clear();
                for (IMapPointBean pointer : list) {
                        LocalPointsBean bean = new LocalPointsBean(
                                (maxWidth - 100) / 2 + pointer.getX() * scale
                                , (maxHeight - 100) / 2 - pointer.getY() * scale
                                , pointer.getPointName());
                        this.mPointerList.add(bean);
                        mRectList.add(new RectF(pointer.getX() - pointerWidth / 2, pointer.getY() - pointerhight, pointer.getX() + pointerWidth / 2, pointer.getY()));
                }
                initBitmap();
        }


        public void setOnFinishListener(IOnStateListener listener) {
                this.mOnStateListner = listener;
        }

        public void setPoints(ArrayList<IMapPointBean> iMapPointBeen) {
                if (Config.isBuKeSi) {
                        setMapPoints3(iMapPointBeen);
                } else {
                        setMapPoints2(iMapPointBeen);
                }
        }

        public interface IOnStateListener {

                void onClick(IMapPointBean mapPointerBean);
        }

        class MyOnGestureListener extends GestureDetector.SimpleOnGestureListener {

                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                        Log.i(getClass().getName(), "onSingleTapUp-----");
                        for (int i = 0; i < mRectList.size(); i++) {
                                if (mRectList.get(i).contains(e.getX(), e.getY())) {
                                        Log.e(TAG, "onSingleTapUp---click--" + (i + 1));
                                        if (mOnStateListner != null) {
                                                mOnStateListner.onClick(mPointerList.get(i));
                                        }
                                        return true;
                                }
                        }
                        return false;
                }

                @Override
                public void onLongPress(MotionEvent e) {
                        Log.i(getClass().getName(), "onLongPress-----");
                }

                @Override
                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                        Log.i(getClass().getName(), "onScroll-----" + distanceX + "--dx---dy--" + distanceX);
                        initMapDate(distanceX, distanceY);
                        return true;
                }

                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                        Log.i(getClass().getName(), "onFling-----");
                        return false;
                }

                @Override
                public void onShowPress(MotionEvent e) {
                        Log.i(getClass().getName(), "onShowPress-----");
                }

                @Override
                public boolean onDown(MotionEvent e) {
                        Log.i(getClass().getName(), "onDown-----");
                        return false;
                }

                @Override
                public boolean onDoubleTap(MotionEvent e) {
                        Log.i(getClass().getName(), "onDoubleTap-----");
                        return false;
                }

                @Override
                public boolean onDoubleTapEvent(MotionEvent e) {
                        Log.i(getClass().getName(), "onDoubleTapEvent-----");
                        return false;
                }

                @Override
                public boolean onSingleTapConfirmed(MotionEvent e) {
                        Log.i(getClass().getName(), "onSingleTapConfirmed-----");
                        return false;
                }
        }

        private void initMapDate(float distanceX, float distanceY) {
                initDotX -= distanceX;
                initDotY -= distanceY;
                invalidate();
        }

        public void destroy() {
                if (mDecoder != null) {
                        mDecoder.recycle();
                }
        }
}
